#include <stdio.h>
#include <string.h>
#include <map>
using namespace std;

const int L_BUF = 65536;
const int N_CHAR = 2;
const char cset[N_CHAR + 1] = "01";
int cidx[128];

struct TrieNode {
    char c, v;
    TrieNode * sons[N_CHAR];
    TrieNode () { memset(this, 0, sizeof(TrieNode)); }
};
TrieNode * trieRoot = NULL;

int nNode = 0, nRecord = 0, nPrefix = 0;

void freeTrie(TrieNode ** rt) {
    if ((*rt) == NULL) return;
    for (int i = 0; i < N_CHAR; ++i) freeTrie(&((*rt)->sons[i]));
    delete (*rt);
    (*rt) = NULL;
}

void initTrie() {
    for (int i = 0; cset[i]; ++i)
        cidx[(int)cset[i]] = i;
    freeTrie(&trieRoot);
    trieRoot = new TrieNode();
    nNode = 1;
    nRecord = nPrefix = 0;
}

int searTrie(char *s) {
    TrieNode * rt;
    int nf = 0;
    for (rt = trieRoot; (rt = rt->sons[cidx[(int)*s]]); ) {
        if (rt->v) ++nf;
        if (*(++s) == 0) break;
    }
    return (nf > 1) ? 1 : 0;
}

TrieNode * insertTrie(char *s) {
    TrieNode * rt, * nxt;
    for (rt = trieRoot; *s; rt = nxt, ++s) {
        nxt = rt->sons[cidx[(int)*s]];
        if (NULL == nxt) {
            rt->sons[cidx[(int)*s]] = nxt = new TrieNode();
            ++nNode;
        }
    }
    rt->v = '\1';
    return rt;
}


const int N = 3600 * 24 * 32;
int countp[N][4];

char buf[1024], ent[1024], binpfx[1024];
int main(int argc, char ** argv)
{
    if (argc != 2) { fprintf(stderr, "usage: count base-time"); return 0; }

    map<long long, unsigned int> ss;
    long long prefixAS = 0LL;
    unsigned int base = 1233446400; // 2009-02-01 00:00:00
    sscanf(argv[1], "%u", &base);

    initTrie();

    int r = 0;
    unsigned int ia, ib, ic, id, im, AS;
    while (gets(buf) != NULL) {
        unsigned int tim;
        sscanf(buf + 2, "%u", &tim);
        if (base > tim) tim = base;
        if (tim - base >= N) continue;
		int len = strlen(buf);
		if (buf[len - 1] == '\n') --len;
		if (buf[len - 1] == '\r') --len;
		
		int j = 2;
        for (; j < len && buf[j] != '|'; ++j) ;

        int i = len - 1, home;
		if (buf[i] == '}' || buf[i] == ')') { // AS Set
			while (i >= 0 && buf[i] != '(' && buf[i] != '{') --i;
			while (i >= 0 && buf[i] == ' ') --i;
		}
		else if (buf[i] < '0' || buf[i] > '9') {
			if (buf[i] == '|') continue;
			fprintf(stderr, "!!1 Error: %s\n", buf);
		}
        for ( ; i >= 0; --i) {
            if (buf[i] == ' ' || buf[i] == '|') break;
            if (buf[i] < '0' || buf[i] > '9') { i = -1; break; }
        } // [i + 1, .): home-AS
		
        if (i >= 0 && buf[len - 1] != '|') {
            if (5 != sscanf(buf + j + 1, "%u.%u.%u.%u/%u", &ia, &ib, &ic, &id, &im)) {
				fprintf(stderr, "!!2 Error: %s\n", buf);
				continue;
			}
            if (1 != sscanf(buf + i + 1, "%u", &AS)) {
				fprintf(stderr, "!!2 Error: %s\n", buf);
				continue;
			}
			
			ia = ((ia << 24) + (ib << 16) + (ic << 8) + id);
			prefixAS = ((long long)ia) | ((long long)im << 32LL) | ((long long)AS << 38LL);

            unsigned int t = ss[prefixAS];
            if (t == 0 || t > tim) {
                ss[prefixAS] = tim;
            }
        }
        if ((++r) % 1000000 == 0) fprintf(stderr, "LINE %d.\n", r);
    }
    fprintf(stderr, "LINE %d.\n", r);

    map<unsigned int, unsigned int> prefixOccur;
    map<unsigned int, unsigned int> prefixChange;

    for (map<long long, unsigned int>::iterator it = ss.begin(); it != ss.end(); ++it) {
        ia = (unsigned int)(it->first & 0xFFFFFFFFLL);
        im = (unsigned int)((it->first >> 32LL) & 0x3FLL);
        if (im < 8) continue;
        ++prefixChange[ia];
		
        unsigned int t = prefixOccur[ia];
        if (t == 0 || t > it->second) {
            prefixOccur[ia] = it->second;
        }
		
		ia >>= (32 - im);
		binpfx[im] = 0;
        for (int i = im - 1; i >= 0; --i) { binpfx[i] = (ia & 1) + '0'; ia >>= 1; }
        insertTrie(binpfx);
    }    
    map<unsigned int, unsigned int> changeCDF;
    int allPfx = prefixChange.size(), sumPfx = 0;
    for (map<unsigned int, unsigned int>::iterator it = prefixChange.begin(); it != prefixChange.end(); ++it)
        changeCDF[it->second] ++;
    for (map<unsigned int, unsigned int>::iterator it = changeCDF.begin(); it != changeCDF.end(); ++it) {
        sumPfx += it->second;
        printf("%3d %8d %8d %.5lf\n", it->first, it->second, sumPfx, sumPfx * 1.0 / allPfx);
    }

    for (map<long long, unsigned int>::iterator it = ss.begin(); it != ss.end(); ++it) {
        ia = (unsigned int)(it->first & 0xFFFFFFFFLL);
        im = (unsigned int)((it->first >> 32LL) & 0x3FLL);
        if (im < 8) continue;
		int isnew = (prefixOccur[ia] == it->second) ? 1 : 0;

		ia >>= (32 - im);
        binpfx[im] = 0;
        for (int i = im - 1; i >= 0; --i) { binpfx[i] = (ia & 1) + '0'; ia >>= 1; }
        int iscov = searTrie(binpfx);
        
        countp[it->second - base][(isnew << 1) | iscov]++;
    }

    printf("uc|un    c|un    nc|n    n|c    ucov    cov    unew    new\n");
    for (int i = 0; i < N; i += 3600 * 24) {
        int s, j;
        for (int isi = 0; isi < 4; ++isi) {
            for (j = i, s = 0; j < i + 3600 * 24; ++j)
                s += countp[j][isi];
            printf("%2d %-8d#\t", i / 3600 / 24, s);
        }

        for (j = i, s = 0; j < i + 3600 * 24; ++j)
            s += countp[j][0] + countp[j][2];
        printf("%2d %-8d#\t", i / 3600 / 24, s);

        for (j = i, s = 0; j < i + 3600 * 24; ++j)
            s += countp[j][1] + countp[j][3];
        printf("%2d %-8d#\t", i / 3600 / 24, s);

        for (j = i, s = 0; j < i + 3600 * 24; ++j)
            s += countp[j][0] + countp[j][1];
        printf("%2d %-8d#\t", i / 3600 / 24, s);

        for (j = i, s = 0; j < i + 3600 * 24; ++j)
            s += countp[j][2] + countp[j][3];
        printf("%2d %-8d", i / 3600 / 24, s);

        printf("\n", i / 3600 / 24, s);
    }
    return 0;
}
